package cn.com.zhbs.common.security;

import cn.com.zhbs.common.dao.SecurityMapper;
import cn.com.zhbs.account.entitys.Account;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import org.springframework.security.web.util.AntPathRequestMatcher;
import org.springframework.security.web.util.RequestMatcher;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * @author 陈治杰
 * @Title: AuthorityInterceptor
 * @Description:
 * @date 2019/2/1315:47
 */
public class AuthorityInterceptor implements HandlerInterceptor {

    private RequestMatcher requestMatcher;

    @Resource
    SecurityMapper securityDao;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        JSONObject allAuth=this.loadAllAuth(httpServletRequest);
        List<String> userAuth=this.loadUserAuth(httpServletRequest);
        Gson gson=new Gson();
        Set set =  gson.fromJson(allAuth.toJSONString(),Map.class).entrySet();
        Iterator i = set.iterator();
        while(i.hasNext()){
            Map.Entry<String, String> entry1=(Map.Entry<String, String>)i.next();
            requestMatcher = new AntPathRequestMatcher(entry1.getKey());
            if (requestMatcher.matches(httpServletRequest)) {
                for(String ua:userAuth){
                    if(ua.equals(entry1.getValue())){
                        return true;
                    }
                }
        }
        }
        JSONObject result=new JSONObject();
        result.put("flag","0");
        result.put("msg","你无权访问");
        responseOutWithJson(httpServletResponse,result);
        return false;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }

    protected JSONObject loadAllAuth(HttpServletRequest httpServletRequest){
        HttpSession session=httpServletRequest.getSession();
        if(session.getAttribute("allAuth")==null){
            List<Map<String,Object>> resources=securityDao.getAuthorityNames();
            JSONObject authMap=new JSONObject();
                for(Map<String,Object> resource:resources){
                    authMap.put(resource.get("resource_string").toString(),resource.get("resource_name"));
                }
            session.setAttribute("allAuth",authMap);
        return authMap;
        }else{
            return JSONObject.parseObject(session.getAttribute("allAuth").toString());
        }


    }
    protected List<String> loadUserAuth(HttpServletRequest httpServletRequest){
        HttpSession session=httpServletRequest.getSession();
        if(session.getAttribute("userAuth")==null){
            List<String> userAuthority=new ArrayList<>();
            if(session.getAttribute(Account.account.toString())!=null){
                userAuthority=securityDao.getUserAuthority(session.getAttribute(Account.account.toString()).toString());
                session.setAttribute("userAuth",userAuthority);
            }
            return userAuthority;
        }else{
            Gson gson=new Gson();
            return gson.fromJson(session.getAttribute("userAuth").toString(),List.class);
        }
    }

    protected void responseOutWithJson(HttpServletResponse response,
                                       JSONObject responseJSONObject) {
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter out = null;
        try {
            out = response.getWriter();
            out.append(responseJSONObject.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}
